from flask import jsonify, request, send_from_directory, abort
from werkzeug.utils import secure_filename
import os
from common.excuteJenkinsJob import ExcuteJenkinsJob
from common.database import DataBase
from interface.model.combinationSql import ServiceVersion
import json
from interface.excel.readExcel import readExcel
from interface.testCase.interfaceTest import Testtest
from common.log import Log
from common.timeJson import ComplexEncoder
from concurrent.futures import ThreadPoolExecutor
executor= ThreadPoolExecutor()

logging = Log()
sv = ServiceVersion()
db = DataBase()
path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
file_path = path + "/resultReport/HtmlReport/接口自动化测试报告.html"
job = ExcuteJenkinsJob()


class interfaceTest:
    def __init__(self):
        self._excel = readExcel()

    # copy报告
    def copyHtml(self):
        f1 = open(file_path, 'r', encoding='utf-8')
        res = f1.read()
        f1.close()
        return res

    # 上传
    def fileUpload(self):
        UPLOAD_PATH = path + '/import_file/'
        f = request.files['file']
        if f:  # 如果文件不为空
            # 清除历史文件
            for parent, dirnames, filename in os.walk(UPLOAD_PATH):
                for name in filename:
                    os.remove(UPLOAD_PATH + name)
                    continue
            upload_path1 = os.path.join(UPLOAD_PATH, secure_filename(f.filename))

            f.save(upload_path1)  # 保存文件
            res = {"msg": "文件上传成功"}
        else:
            res = {"msg": "没有上传文件"}
        return json.dumps(res, ensure_ascii=False)  # 防止出现乱码

    # 进行用例上传，用例文件保存至../import_file下面
    def uploadCase(self):
        base_info = dict(request.form)
        file = request.files['file']
        content = file.read()
        case_list = self._excel.read_excel_to_case(content)
        if self.writeCase(base_info, case_list):
            return json.dumps({"code": 1}, ensure_ascii=False)  # 防止出现乱码
        else:
            return json.dumps({"code": 0, "msg": f"用例导入错误，请检查内容:{case_list}"}, ensure_ascii=False)

    # 下载
    def download(self):
        Path = path + "/resultReport/HtmlReport/"
        for parent, dirnames, file in os.walk(Path):
            for filnane in file:
                return send_from_directory(Path, filnane, as_attachment=True)
        abort(404)

    def readExcelCase(self):
        readCase = readExcel().get_xls_view()
        return jsonify(readCase)

    # 导入创建用例
    def writeCase(self, base_info, case_list):
        try:
            sql = f'''select id from project_version where project_id={base_info["project_id"]} and service_id={base_info["service_id"]} and version_name="{base_info["version_name"]}";'''
            version_id = db.test_platform([sql])
            sql = sv.add_import_case(base_info, version_id[0]["id"], case_list)
            db.test_platform(sql, m='w')
            return True
        except Exception as e:
            return False

    # 单条创建用例
    def saveOneCase(self):
        data = json.loads(request.data)
        try:
            sql = sv.select_project_path_url(data["case_path"])
            data = db.test_platform(sql)
            if bool(data):
                sql = sv.add_case(data)
                db.test_platform(sql, m='w')
            else:
                sql = sv.add_case(data)
                db.test_platform(sql, m='w')
            return jsonify({'success': 'true'})
        except Exception as e:
            return jsonify({'success': 'false', 'msg': str(e)})

    # 用例更新
    def updateOneCase(self):
        data = json.loads(request.data)
        try:
            sql = sv.select_project_path_url(data["case_path"])
            data = db.test_platform(sql)
            if bool(data):
                sql = sv.add_case(data)
                db.test_platform(sql, m='w')
            else:
                sql = sv.add_case(data)
                db.test_platform(sql, m='w')
            return jsonify({'success': 'true'})
        except Exception as e:
            return jsonify({'success': 'false', 'msg': str(e)})

    # 多版本查询用例
    def selectCaseall(self):
        data = json.loads(request.data)
        caseSql = sv.select_case_(data)
        caseBody = db.test_platform(caseSql)
        if len(caseBody):
            return jsonify(caseBody)
        else:
            return jsonify({"case": "null"})

    # 扫描java项目接口路径
    def scanJavaFile(self):
        try:
            service_name = request.args.get("service_name")
            branch_name = request.args.get("branch_name")
            scanResult = job.excuteJob(service_name, branch_name)
            if scanResult:
                pass
            # caseurl = Testtest().testCaseUrl(self.testcase_xls)
            # resultEnd = self.contrast(eval(scanResult), caseurl)
            # return jsonify(resultEnd)
            else:
                return {"disparate": "", "identical": "", "testDis": ""}
        except Exception as e:
            logging.error(e)

    def selectAllBranch(self):
        '''
        查询所有分支
        :return:
        '''
        service_name = request.args.get("service_name")
        allBranch = job.getAllBranch(service_name)
        if allBranch:
            return jsonify({"data": allBranch["values"]})
        else:
            return jsonify({"data": {"name": "None"}})

    def contrast(self, javabodys, checks):
        '''
        参数对比
        :param javabodys:
        :param checks:
        :return:
        '''
        javabody = list(set(javabodys))
        check = list(set(checks))
        # java路径存在用例不存在的
        disparate = []
        # 项目和用例一致
        identical = []
        # 用例与项目不同的
        testDis = []
        for javacase in javabody:
            if javacase in check:
                identical.append(javabody)
            elif javacase not in check:
                disparate.append(javacase)
        for excelcase in check:
            if excelcase not in javabody:
                testDis.append(excelcase)
        return {"disparate": disparate, "identical": identical, "testDis": testDis}

    # 执行用例
    def start_case(self):
        data = json.loads(request.data)
        try:
            result = Testtest().testInterface(data["project_id"], [data["caseall"]])
            if result[0]["success"] == 'true':
                sql = sv.update_case_status(data["caseall"]["id"], 2)
                db.test_platform(sql, m='w')
                return jsonify(result[0]['response'])
            elif result[0]["success"] == 'false':
                sql = sv.update_case_status(data["caseall"]["id"], 3)
                db.test_platform(sql, m='w')
                return jsonify(result[0]["response"])
            else:
                sql = sv.update_case_status(data["caseall"]["id"], 1)
                db.test_platform(sql, m='w')
                return jsonify('执行异常ERROR')
        except Exception as e:
            return {"error", str(e)}

    # 执行接口自动化
    def interfaceApp(self):
        from interface.view.apicommon import save_case_log
        global data, resp
        try:
            data = json.loads(request.data)
            resp = Testtest().testInterface(data['project_id'], data['caseList'])
            return json.dumps(resp, cls=ComplexEncoder)
        finally:
            executor.submit(save_case_log(sv, data, db, resp))

    def select_service_log(self):
        '''根据服务查询用例执行版本记录'''
        data = json.loads(request.data)
        sql = sv.select_case_service(data["service_id"])
        log_body = db.test_platform(sql)
        return json.dumps(log_body)

    def select_log(self):
        # 查询日志执行记录
        data = json.loads(request.data)
        sql = sv.select_case_version_id(data)
        log_body = db.test_platform(sql)
        return json.dumps(log_body, cls=ComplexEncoder)

    def select_case_res_log(self):
        # 查询历史用例执行结果
        id = request.args.get('id')
        sql = sv.select_case_res_log(id)
        res = db.test_platform(sql)
        return json.dumps(res, cls=ComplexEncoder)

    # 删除用例
    def case_delete(self):
        id = request.args.get('id')
        sql = sv.delete_case(id)
        res = db.test_platform(sql, m='w')
        if res["code"] == 1:
            return {"success": "true", "msg": "删除成功"}
        else:
            return {"success": "false", "msg": "删除失败"}

    # 批量删除用例
    def case_more_delete(self):
        ids = json.loads(request.data)
        id = ids['id']
        sql = sv.delete_case(id)
        res = db.test_platform(sql, m="w")
        if res["code"] == 1:
            return {"success": "true", "msg": "批量删除用例成功"}
        else:
            return {"success": "false", "msg": "批量删除用例失败"}

    # 新增用例
    def save_case(self):
        data = json.loads(request.data)
        print('data用例数据', data)
        sql = sv.add_case(data)
        print("sql", sql)
        res = db.test_platform(sql, m='w')
        return jsonify(res)

    # 根据id查询某条用例内容，用于渲染"修改用例"弹窗
    def get_one_case(self):
        id = request.args.get('id')
        sql = sv.select_case_id(id)
        res = db.test_platform(sql)
        return jsonify(res)

    # 修改单条用例
    def update_case_info(self):
        # id = request.args.get('id')
        data = json.loads(request.data)
        sql = sv.update_case_info(data)
        res = db.test_platform(sql, m="w")
        if res["code"] == 1:
            return {"success": "true", "msg": "修改成功"}
        else:
            return {"success": "false", "msg": "修改失败"}
